#include"mprpcchannel.h"
#include"rpcheader.pb.h"
#include"mprpc.h"
#include<string>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<cstring>
#include<stdlib.h>
#include<arpa/inet.h>  
#include"mprpccontroller.h"
#include"zookeeperuti.h"

void MprpcChannel::CallMethod(const google::protobuf::MethodDescriptor* method,
                google::protobuf::RpcController* controller, const google::protobuf::Message* request,
                google::protobuf::Message* response, google::protobuf::Closure* done)
{
    //获取对象描述符
    const google::protobuf::ServiceDescriptor* Desc=method->service();

    std::string servie_name=Desc->name();
    std::string method_name=method->name();

    //报文序列化
    uint32_t args_size=0;
    std::string request_str;
    if(!request->SerializeToString(&request_str))
    {
        controller->SetFailed("request SerializeToString false!");
        std::cout << "request SerializeToString false!" << std::endl;
        return;
    }
    args_size=request_str.size();
    
    //发送报文
    std::string send_str;
    

    //生成报头
    mprpc::RpcHeader header;
    header.set_method_name(method_name);
    header.set_service_name(servie_name);
    header.set_args_size(args_size);
    //报头序列化
    std::string header_str;
    if(!header.SerializePartialToString(&header_str))
    {
        controller->SetFailed("header SerializeToString false!");
        std::cout << "header SerializeToString false!" << std::endl;
        return;
    }
    int header_size=header_str.size();

    //填入报头长度
    send_str.insert(0,std::string((char*)&header_size,4));
    //填入报头
    send_str+=header_str;
    //填入报文
    send_str+=request_str;

    //TCP套接字
    int Socket =socket(AF_INET, SOCK_STREAM, 0);
    if (Socket == -1) 
    {
        controller->SetFailed("Error creating socket!");
        std::cerr << "Error creating socket!" << std::endl;
        return;
    }    

    // std::string ip=Mprpc::GetConfig().GetItem("rpcserverip");
    // uint16_t port=atoi(Mprpc::GetConfig().GetItem("rpcserverport").c_str());
    // 通过服务注册中心
    ZkClient zkcli;
    zkcli.Start();
    std::string method_path="/"+servie_name+"/"+method_name;
    std::string host_data=zkcli.GetData(method_path.c_str());
    if(host_data=="")
    {
        controller->SetFailed(method_path+"not exist");
        return;
    }

    int idx=host_data.find(":");
    if(idx==-1)
    {
        controller->SetFailed(method_path+"format no trut");
        return;
    }
    std::string ip=host_data.substr(0,idx);
    uint16_t port=atoi(host_data.substr(idx+1,host_data.size()-idx).c_str());
    
    struct sockaddr_in serverAddress;
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(port);  // 端口号
    serverAddress.sin_addr.s_addr = inet_addr(ip.c_str());  // 服务器 IP 地址

    //连接
    if(connect(Socket,(sockaddr*)&serverAddress,sizeof(serverAddress))==-1)
    {
        controller->SetFailed("connect error!");
        std::cerr << "connect error!" << std::endl;
        close(Socket);
        return;
    }

    // 发送数据
    ssize_t send_size=send(Socket,send_str.c_str(), send_str.size(), 0);
    if(send_size == -1) 
    {
        controller->SetFailed("Error sending data");
        std::cerr << "Error sending data" << std::endl;
        close(Socket);
        return;
    }

    //接收响应
    char buffer[1024];
    int recv_size=recv(Socket, buffer, sizeof(buffer), 0);
    if(recv_size == -1) 
    {
        controller->SetFailed("Error receiving data");
        std::cerr << "Error receiving data" << std::endl;
        close(Socket);
        return;
    }


    if(!response->ParseFromArray(buffer,recv_size))
    {
        controller->SetFailed("response parse error!");
        std::cerr << "response parse error!" << std::endl;
        close(Socket);
        return;
    }

    close(Socket);
}
